#ifndef Command_First
#define Command_First
#ifdef __GNUG__
#pragma interface
#endif

#include "Object.h"
#include "Point.h"

class Clipper;

enum TrackPhase {
	eTrackPress,
	eTrackMove,
	eTrackRelease,
	eTrackIdle,
	eTrackExit
};

enum CommandState {
	eCmdStateNew,
	eCmdStateDone,
	eCmdStateNotDone,
	eCmdStateFinished
};

enum CommandType {
	eCmdTypeNormal,
	eCmdTypeCantUndo,
	eCmdTypeNoChange
};

enum CommandFlags {
	eCmdMoveEvents   = BIT(eObjLast+1),
	eCmdIdleEvents   = BIT(eObjLast+2),
	eCmdFullScreen   = BIT(eObjLast+3),
	eCmdNoReplFeedback= BIT(eObjLast+4),
	eCmdDefault      = 0,
	eCmdLast         = eObjLast + 4
};

class Command: public Object {
	int CmdNumber;
	const char *CmdName;
	CommandState state;
	CommandType type;

public:
	MetaDef(Command);

	Command(int= 0, const char *CmdName= 0, CommandType t= eCmdTypeNormal);
	Command(const char *CmdName, CommandType t= eCmdTypeNormal);

	void SetName(const char *name)
		{ CmdName= name; }
	const char *GetName()
		{ return CmdName; }
	const char *GetUndoName();
	void SetId(int cmd)
		{ CmdNumber= cmd; }
	int GetId()
		{ return CmdNumber; }
	void SetType(CommandType t)
		{ type= t; }
	CommandType GetType()
		{ return type; }
		
	void Finish();
	int Perform();
	virtual void Done(Command *newCommand);

protected:
	virtual void Commit();
	virtual void UndoIt();
	virtual void DoIt();
	virtual void RedoIt();
	void InspectorId(char *buf, int sz);

friend Clipper;
	virtual void TrackConstrain(Point anchorPoint, Point previousPoint,
															Point *nextPoint);
	virtual void TrackFeedback(Point anchorPoint, Point previousPoint,
			bool turnItOn);

	virtual Command *TrackMouse(TrackPhase aTrackPhase, Point anchorPoint,
			Point previousPoint, Point nextPoint);
};

extern Command
	*gNoChanges,
	*gResetUndo;

#endif

